/*
 This file is part of Musimage, a project which makes possible listen to music
 and, at the same time, watch pictures related with that music.
 Copyright (C) 2006  David Garcia Narbona 

 Musimage is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 Musimage is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Musimage; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package broker;

import java.io.IOException;
import java.util.Vector;
import java.util.Enumeration;

import jade.core.Agent;
import jade.lang.acl.ACLMessage;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.UnreadableException;

import message.MessageStructure;

// Clase que hace el tratamiento d ela peticion del cliente, busca
// en la base de datos las imagenes adecuadas a las canciones de la
// peticion y si no encuentra la cancion pide al servidor de archivos
// RDF el archivo RDF de esa cancion
public class ProcessClientRequest extends OneShotBehaviour {

	// ** Atributos **///////////////////////////////////////////
	private ACLMessage clientRequest;

	private MessageStructure URLs;

	// //////////////////////////////////////////////////////////

	// ** Metodos **//////////////////////////////////////////////

	// Constructor
	public ProcessClientRequest(Agent _agent, ACLMessage _requestMessage) {

		clientRequest = _requestMessage;
	}

	public void action() {

		replyAgreement();
		processRequest();
	}

	// Metodo que extrae las canciones del mensaje y copmrueba si las tiene
	// archivadas
	// en la base de datos para devolverle una respuesta al cliente
	private void processRequest() {

		try {

			MessageStructure iD3messageDataStructure = (MessageStructure) clientRequest
					.getContentObject();

			// CONTROL GOOGLE
			if (iD3messageDataStructure.getLinkParameter() == -1) {

				Enumeration e = iD3messageDataStructure.getFullData()
						.elements();

				URLs = new MessageStructure(iD3messageDataStructure
						.getFullData().size());

				Vector cancionesEnProceso = new Vector(iD3messageDataStructure
						.getFullData().size());

				int idThread = 0;

				while (e.hasMoreElements()) {

					Vector singleID3 = (Vector) e.nextElement();

					String songName = (String) singleID3.elementAt(2);
					String autorName = (String) singleID3.elementAt(1);

					cancionesEnProceso
							.add(new InternetImageResearchThreadingExecution(
									new LookForImagesInGOOgle(songName), this,
									idThread));

					InternetImageResearchThreadingExecution internetImageResearchThreadingExecution = (InternetImageResearchThreadingExecution) cancionesEnProceso
							.lastElement();
					internetImageResearchThreadingExecution.start();

					idThread++;

				}

				for (int i = 0; i < cancionesEnProceso.size(); i++) {

					try {
						InternetImageResearchThreadingExecution internetImageResearchThreadingExecution = (InternetImageResearchThreadingExecution) cancionesEnProceso
								.get(i);
						internetImageResearchThreadingExecution.join();
					} catch (InterruptedException ie) {

						System.err
								.println("ERROR in ProcessClientRequest class on processRequest() method: "
										+ ie.getMessage());
					}
				}

				replyInform(URLs);
			} else {// BUSQUEDA EN BD

				Enumeration e = iD3messageDataStructure.getFullData()
						.elements();

				URLs = new MessageStructure(iD3messageDataStructure
						.getFullData().size());

				Vector cancionesEnProceso = new Vector(iD3messageDataStructure
						.getFullData().size());

				int idThread = 0;

				while (e.hasMoreElements()) {

					Vector singleID3 = (Vector) e.nextElement();

					String songName = (String) singleID3.elementAt(2);
					String autorName = (String) singleID3.elementAt(1);

					cancionesEnProceso.add(new ImageResearchThreadingExecution(
							new DataBaseManager(), this, songName, autorName,
							iD3messageDataStructure.getLinkParameter(),
							idThread));

					ImageResearchThreadingExecution imageResearchThreadingExecution = (ImageResearchThreadingExecution) cancionesEnProceso
							.lastElement();
					imageResearchThreadingExecution.start();

					idThread++;

				}

				for (int i = 0; i < cancionesEnProceso.size(); i++) {

					try {
						ImageResearchThreadingExecution imageResearchThreadingExecution = (ImageResearchThreadingExecution) cancionesEnProceso
								.get(i);
						imageResearchThreadingExecution.join();
					} catch (InterruptedException ie) {

						System.err
								.println("ERROR in ProcessClientRequest class on processRequest() method: "
										+ ie.getMessage());
					}
				}

				replyInform(URLs);
			}
		} catch (UnreadableException e3) {

			System.err
					.println("ERROR in ProcessClientRequest class on processRequest() method: "
							+ e3.getMessage());
		} catch (ClassCastException e) {

			System.err
					.println("ERROR in ProcessClientRequest class on processRequest() method: "
							+ e.getMessage());
		}
	}

	// Metodo que responde al cliente conforme ha recibido la peticion
	private void replyAgreement() {

		ACLMessage reply = clientRequest.createReply();

		reply.setPerformative(ACLMessage.AGREE);

		myAgent.send(reply);
	}

	// Metodo que crea y envia el mensaje de respuesta para el cliente con el
	// que mantiene
	// la comunicacion
	private void replyInform(MessageStructure URL) {

		// Prepara la respuesta para el cliente
		ACLMessage reponse = clientRequest.createReply();
		reponse.setPerformative(ACLMessage.INFORM);

		try {
			reponse.setContentObject(URL);
		} catch (IOException e) {
			e.printStackTrace();
		}

		myAgent.send(reponse);
	}

	// Metodo que consulta al RDFServer por las canciones que el broker no tiene
	// archivadas
	public void requestRDFServer(String songName, String autorName) {

		myAgent.addBehaviour(new ConversationThread(myAgent, songName,
				autorName));
	}

	// Metodo al que acceden los diferentes threads en los que se
	// ejecutan las busquedas de imagenes para cada cancion
	public synchronized void setMessageStructure(int index, Vector songURL) {

		URLs.add(index, songURL);
	}

	// ///////////////////////////////////////////////////////////
}
